﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
 
namespace Solidi
{
	public class PooledLifestyle : IDependencyLifestyle
	{
		private Stack<object> _tokens = new Stack<object>();
		private TimeSpan _timeout;
		private int _poolSize;

		public PooledLifestyle(int poolSize, TimeSpan timeout)
		{
			_poolSize = poolSize;
			_timeout = timeout;
		}

		public object ResolveToken(object contextId)
		{
			lock (_tokens)
			{
				if (_poolSize < 1)
				{
					if (!Monitor.Wait(_tokens, _timeout))
					{
						throw new TimeoutException("Timeout expired waiting to obtain pooled object.");
					}
				}

				_poolSize--;

				if (_tokens.Count > 0)
				{
					return _tokens.Pop();
				}
				else
				{
					return new object();
				}
			}
		}

		public bool ReleaseToken(object token)
		{
			lock (_tokens)
			{
				_tokens.Push(token);

				_poolSize++;

				Monitor.Pulse(_tokens);
			}

			return false;
		}
	}
}
